import TRTC from 'trtc-js-sdk'; // 从 trtc-js-sdk 导入 TRTC
import type { Client, LocalStream } from 'trtc-js-sdk'; // 从 trtc-js-sdk 导入类型 Client 和 LocalStream
import { genTestUserSig } from '@/utils/generateTestUserSig'; // 从 utils 目录导入 genTestUserSig 函数
import type { ClientOptions } from '@/types/type'; // 从 types 目录导入类型 ClientOptions
import appStore from '@/store/index'; // 从 store 目录导入 appStore

class ShareClient {
  private sdkAppId: number; // 定义 sdkAppId 属性，类型为 number

  private userId: string; // 定义 userId 属性，类型为 string

  private secretKey: string; // 定义 secretKey 属性，类型为 string

  private roomId: number; // 定义 roomId 属性，类型为 number

  private client!: Client; // 定义 client 属性，类型为 Client

  private localStream!: LocalStream | null; // 定义 localStream 属性，类型为 LocalStream 或 null

  private isJoined: boolean; // 定义 isJoined 属性，类型为 boolean

  private isPublished: boolean; // 定义 isPublished 属性，类型为 boolean

  private isLeaving: boolean; // 定义 isLeaving 属性，类型为 boolean

  constructor(options: ClientOptions) {
    const { sdkAppId, userId, roomId, secretKey } = options; // 从 options 中解构出 sdkAppId, userId, roomId 和 secretKey

    this.sdkAppId = sdkAppId; // 初始化 sdkAppId
    this.userId = userId; // 初始化 userId
    this.secretKey = secretKey!; // 初始化 secretKey
    this.roomId = roomId; // 初始化 roomId

    this.isJoined = false; // 初始化 isJoined 为 false
    this.isPublished = false; // 初始化 isPublished 为 false
    this.isLeaving = false; // 初始化 isLeaving 为 false

    this.initClient(); // 调用 initClient 方法初始化客户端
  }

  getShareLocalStream() {
    return this.localStream; // 返回 localStream
  }

  initClient() {
    const { userSig } = genTestUserSig({
      sdkAppId: this.sdkAppId, // 传入 sdkAppId
      userId: this.userId, // 传入 userId
      secretKey: this.secretKey, // 传入 secretKey
    });

    try {
      this.client = TRTC.createClient({
        mode: 'rtc', // 设置模式为 'rtc'
        sdkAppId: this.sdkAppId, // 传入 sdkAppId
        userId: this.userId, // 传入 userId
        userSig, // 传入 userSig
      });
      console.log(`Client [${this.userId}] created.`); // 打印客户端创建成功的日志
      this.installEventHandlers(); // 安装事件处理程序
    } catch (e) {
      console.error(`Failed to create Client [${this.userId}].`); // 打印客户端创建失败的错误日志
    }
  }

  async initLocalStream() {
    try {
      this.localStream = TRTC.createStream({
        audio: false, // 不启用音频
        screen: true, // 启用屏幕共享
        userId: this.userId, // 传入 userId
      });
      this.localStream.setScreenProfile({
        width: 1920, // 设置屏幕宽度为 1920
        height: 1080, // 设置屏幕高度为 1080
        frameRate: 30, // 设置帧率为 30
        bitrate: 2000, // 设置比特率为 2000
      });
      await this.localStream.initialize(); // 初始化本地流
      this.localStream.on('screen-sharing-stopped', () => {
        console.log('ShareStream video track ended'); // 打印屏幕共享结束的日志
        const store = appStore(); // 获取应用状态
        store.isShared = false; // 设置共享状态为 false
        this.leave(); // 调用 leave 方法离开房间
      });
      await this.client.join({ roomId: this.roomId }); // 加入房间
      this.isJoined = true; // 设置 isJoined 为 true
      return this.localStream; // 返回本地流
    } catch (error: any) {
      console.error(`ShareStream failed to initialize. Error: ${error}`); // 打印初始化失败的错误日志
      return null; // 返回 null
    }
  }

  // 加入房间
  async join() {
    console.log('join room clicked'); // 打印点击加入房间的日志

    try {
      // await this.client.join({ roomId: this.roomId });
      await this.initLocalStream(); // 初始化本地流
    } catch (e) {
      console.error('join room failed', e); // 打印加入房间失败的错误日志
    }
  }

  async publish() {
    if (!this.isJoined) {
      console.warn('call publish()- please join() firstly'); // 如果未加入房间，打印警告日志
      return;
    }
    if (this.isPublished) {
      console.warn('duplicate publish() observed'); // 如果已经发布，打印重复发布的警告日志
      return;
    }
    try {
      await this.client.publish(this.localStream!); // 发布本地流
      console.log('ShareStream is published successfully'); // 打印发布成功的日志
      this.isPublished = true; // 设置 isPublished 为 true
    } catch (error: any) {
      console.error(`ShareStream is failed to publish. Error: ${error}`); // 打印发布失败的错误日志
    }
  }

  async unpublish() {
    if (!this.isJoined) {
      console.warn('unpublish() - please join() firstly'); // 如果未加入房间，打印警告日志
      return;
    }
    if (!this.isPublished) {
      console.warn('call unpublish() - you have not published yet'); // 如果未发布，打印警告日志
      return;
    }
    try {
      if (this.localStream) {
        await this.client.unpublish(this.localStream); // 取消发布本地流
      }
      this.isPublished = false; // 设置 isPublished 为 false
      console.log('Unpublish ShareStream success'); // 打印取消发布成功的日志
    } catch (error) {
      console.error('unpublish failed', error); // 打印取消发布失败的错误日志
    }
  }

  async leave() {
    if (!this.isJoined) {
      console.warn('leave() - please join() firstly'); // 如果未加入房间，打印警告日志
      return;
    }
    if (this.isLeaving) {
      console.warn('duplicate leave() observed'); // 如果已经在离开，打印重复离开的警告日志
      return;
    }
    if (this.isPublished) {
      await this.unpublish(); // 如果已发布，取消发布
    }
    try {
      this.isLeaving = true; // 设置 isLeaving 为 true

      await this.client.leave(); // 离开房间
      this.isJoined = false; // 设置 isJoined 为 false
      console.log('Local share client leave room success'); // 打印离开房间成功的日志

      if (this.localStream) {
        this.localStream.stop(); // 停止本地流
        this.localStream.close(); // 关闭本地流
        this.localStream = null; // 将 localStream 设置为 null
      }
      this.isLeaving = false; // 设置 isLeaving 为 false
    } catch (error) {
      console.error('leave failed', error); // 打印离开房间失败的错误日志
    }
  }

  installEventHandlers() {
    this.client.on('error', this.handleError.bind(this)); // 监听客户端错误事件
    this.client.on('client-banned', this.handleBanned.bind(this)); // 监听客户端被禁事件
    this.client.on('stream-subscribed', this.handleStreamSubscribed.bind(this)); // 监听流订阅事件
  }

  handleError(error: any) {
    console.error('client error', error); // 打印客户端错误日志
  }

  handleBanned(event: any) {
    console.warn(`client has been banned for ${event.reason}`); // 打印客户端被禁的警告日志
  }

  handleStreamSubscribed(event: any) {
    const remoteStream = event.stream; // 获取远程流
    const id = remoteStream.getId(); // 获取远程流的 ID
    const userId = remoteStream.getUserId(); // 获取远程流的用户 ID
    console.log(`remote stream subscribed: [${userId}] ID: ${id} type: ${remoteStream.getType()}`); // 打印远程流订阅成功的日志

    this.client.unsubscribe(remoteStream); // 取消订阅远程流
  }
}

export default ShareClient; // 导出 ShareClient 类